package com.lyz.monitor.impl;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.log4j.Logger;

import com.lyz.config.ConfigFactory;
import com.lyz.config.IConfig;
import com.lyz.core.impl.TransferService;
import com.lyz.mail.SendMail;
import com.lyz.monitor.AbstractMonitorData;
import com.lyz.monitor.IMonitor;
import com.lyz.monitor.ShortMessage;
import com.lyz.util.HostUtil;
import com.lyz.util.PropertiesUtil;
import com.lyz.util.SleepUtil;

/**
 * 线程监控,监控服务线程是否存活，并重启死掉的线程
 * @author luyongzhao
 *
 */
public class ThreadMonitor extends Thread implements IMonitor{
	
	private static final Logger logger = Logger.getLogger(ThreadMonitor.class);
	
	List<AbstractMonitorData> dataList = new LinkedList<AbstractMonitorData>();
	
	private static AtomicReference<ThreadMonitor> instance = new AtomicReference<ThreadMonitor>();
	
//	private static PropertiesUtil config = PropertiesUtil.getInstance();
	/*默认1分钟检测一次*/
	private final int interval = 1000*60;
	
	private static final IConfig config = ConfigFactory.getConfig();
	
	private ThreadMonitor(){
		
		super("threadMonitor");
		/*设置成守护线程*/
		this.setDaemon(true);
	}
	
	public static ThreadMonitor getInstance(){
		
		if(instance.get() == null){
			instance.compareAndSet(null, new ThreadMonitor());
		}
		
		return instance.get();
	}

	@Override
	public void addMonitorData(AbstractMonitorData data) {
		
		if(data == null){
			return;
		}
		logger.info(data.getTag()+" is added into thread monitor...");
		dataList.add(data);
		
	}

	@Override
	public void alert(int level, AbstractMonitorData data) {
		try {
			if(level == IMonitor.LEVEL_LOG){
				logger.warn(data.getAletMsg());
			}else if(level == IMonitor.LEVEL_EMAIL){
				SendMail.sendMail(data.getAletMsg()+"("+HostUtil.getHostIpAddress()+")", data.getAletMsg()
						,config.getMailHost(),config.getMailFrom(),config.getMailTo());
			}else if(level == IMonitor.LEVEL_MESSAGE){
				ShortMessage.getInstance().sendShortMessage(config.getMsgPhoneNum(), data.getAletMsg());
			}else{
				logger.warn("unknown level:"+level);
			}
		} catch (Exception e) {
			logger.warn("exception when alert!",e);
		}
		
	}
	
	
	public void run(){
		logger.info("thread monitor is start...");
		while(true){
			logger.info("thread monitor is run...");
			SleepUtil.sleepForCertainTime(interval);
			for(AbstractMonitorData data : dataList){
				if(data == null){
					continue;
				}
				/*如果符合警告条件，并且没有发送过警告，则发送*/
				if(!data.isAlert()){
					int level = data.need2Alert();
					if(level >= 0){
						alert(level,data);
						/*重启线程*/
						restartService(data);
					}else{
						/*如果警告条件未满足，或者已经跟上了进度，则重置*/
						data.setAlert(false);
					}
					
				}
			}
		}
	}
	
	private void restartService(AbstractMonitorData data){
		
		try {
			if(data == null){
				return;
			}
			TransferService service = (TransferService)data.getObj();
			TransferService newService = new TransferService(service.getTag());
			newService.start();
			data.setObj(newService);
		} catch (Exception e) {
			logger.error("fail to restart service thread...",e);
		}
	}

}
